手把手教会你工控环境下的串口调试
工控环境中,广泛存在串口通信,串口通信连接了上位机和下位机。
几乎所有工控设备,PLC,DCS,嵌入式平台,物联网设备,网络设备都具备串口,支持串口通信,甚至将串口保留为最基础的调试接口。从现场情况看,大部分设备允许从串口不经认证地读取,操作敏感数据,刷固件等。即使没有外接串口,也可以在PCB板上找到串口接出的pin针脚或者焊点。
很多人认为串口相对安全,通过串口交换业务数据的两张网,相对安全性高,中毒的机率小。实际上,作为一种原始的通信方式,串口并不具备天然的安全属性。
著名的方程式泄露工具集Expanding Pulley里面,就有关于串口监控的程序SerialSniffer_Implant.dll。开源和商业的串口监控程序也有许多。
我们这篇文章以RS232为例,探讨串口通讯的监听和中间人攻击可行性。
RS232串口的基本原理:RS232在两台终端设备之间提供了一个异步通讯方式,也就是全双工通讯,9针的串口线中的2,3号线分别是通讯两端的Rx和Tx,两端的设备可以在自己作为Tx的线上随时发送数据,不受接受数据的干扰。这种方式为上层提供了灵活的配置空间,例如下位机可以完全不顾上位机是否存在,持续向串口线上写入业务汇报数据;下位机可以配置为不接受上位机传来的任何指令,实现一种原始的网闸效果;2,3两根线上甚至可以配置不同的波特率,用于对抗一部分监听攻击者。
但是,上层的应用层协议通常需要一个半双工的连接,多数上层协议是主从模式或者说服务器/客户端模式,其中一方负责建立连接,另一方不主动发起连接;而连接建立后,一方发起数据查询,另一方负责响应数据,同时只有一方在发送数据。
我们首先考虑硬件层面的监听(或者说调试)
首先,如果有示波器,简单搭线即可监听串口上的电平波动,通过一些专业计算,就可以获取原始的0,1序列,最后转换为数据。
但是如果希望监听端口也是一个COM口,那么我们可以自己动手做一根监听线。
如果上层协议决定了RS232工作在半双工模式,那么制作一根监听线就比较容易了。
半双工RS232嗅探线
两端的数据线都接到监听口的Rx上
以上在UART环境下已经足够了。但是如果目标监控设备真的工作在全双工模式下,两边同时发送数据就会导致监听到乱码。这时我们可以做一根全双工的监听线,将双向数据导出到两个监听口上。
在监听主机上随意配合一个串口读取工具就可以实现数据监听了。
以上是在物理接触上下位机的情况下,我们可以通过接线的方式实现监听。但是在更多的情况下,我们需要一个软件方案。因为多数攻击者,攻击病毒或者脚本,可能只是首先获取到了一个上位机权限,但却不能改造现场的物理接线。而且往往COM接口只能打开一次,已经被原应用占用。我们不能通过minicom,超级终端或putty之类的软件直接打开对应的COM口来观察数据。
这时如何对串口数据进行监听攻击呢?
这个情况下,有一些软件可以协助我们解决这个问题(通常上位机我们认为是一台Windows)
这类软件比较多,我们只介绍三款:两款基于Windows环境,一款基于Linux:
SUDT的AccessPort
这是一个免费绿色软件,优点也比较多,软件体积小,支持中文,支持16进制的展示,支持同时监控多个串口,支持动态修改波特率。操作系统支持度高,可以支持从windows 9x/2K/XP/Win7/Win8/Win10,在64位系统上也能正常运行,能够在连接开始时识别波特率设置。
缺点:必须在目标软件启动打开串口之前启动;自定义的波特率最高只支持到256000,某些UART设备的921600不支持;在硬件热插拔情况下可能导致蓝屏。
HHD的Free Serial Analyzer
是Free Device Monitoring Studio的一部分,功能相对较多,可以针对USB,串口,HID设备,TCP/IP进行监控,可以桥接不同的设备类型,可以自定义脚本,可以录制回放数据,支持MODBUS,支持远程监控,但是很多功能只能免费使用15天。
Linux环境下的sersniff
是一个非常基础的工具,可以用来获取单向的串口数据。
sersniff -i /dev/ttyS0 -o /dev/ttyS1 -b 9600 |
上述方案还是只能软件实现sniffer的功能,如果想要实现中间人攻击,篡改串口通讯数据,该怎么办呢?
根据桥接串口的思想,我们只要自己实现一对桥接的串口,将上位机的工作端口换到我们虚拟出来的串口上,就可以了。
现成的工具有VSPE(Virtual Serial Port Emulater),类似的工具还有VSPD,不再展开介绍。
使用VSPE最基本的功能,创建一个Connector,一个可以打开两次的虚拟串口,命名为COM3。
假设原始上位机程序读写COM4,波特率为921600,我们首先通过修改上位机软件配置,使其工作于我们创建的COM3。然后我们需要再自己写一个程序,将COM3和COM4桥接起来。
#serial_mitm.py #by lijunsheng import sys import serial from serial import SerialException baud_rate1 = 921600 #whatever baudrate you like baud_rate2 = 921600 com_port1 = 'COM3' com_port2 = 'COM4' try: listener = serial.Serial(com_port1, baud_rate1) except SerialException, e: print e.message sys.exit() try: forwarder = serial.Serial(com_port2, baud_rate2) except SerialException, e: print e.message listener.close() sys.exit()
while 1: if listener.in_waiting > 0: serial_length = listener.in_waiting serial_buffer = listener.read(serial_length) #do anything to the buffer before forward it if serial_buffer == "CLOSE": # we need a break, or we will not able to open the port after we kill the proxy break else: forwarder.write(serial_buffer) if forwarder.in_waiting > 0: serial_length = forwarder.in_waiting serial_buffer = forwarder.read(serial_length) #DO what you like to the replied buffer. listener.write(serial_buffer) print "Closing both of the serial ports..." listener.close() forwarder.close() sys.exit() |
通过这样的操作,我们就可以任意篡改串口通信数据了。同时,也自然获取了软件监听能力,可以不必再借助前述的那些软件监听工具。
有了中间人攻击的手段,我们就可以借助上位机,在不更改其软件/绕过其软件注册/绕过软件权限限制的情况下,对下位机进行随心所欲的修改和发送指令。当然,同时我们也可以模拟下位机设备,随意欺骗上位机。并且都是在通信双方不能发现的前提下做到的。
威努特简介北京威努特技术有限公司(以下简称“威努特”),成立于2014年,是国内专注于工控安全领域的国家高新技术企业,全球仅六家荣获国际自动化协会安全合规学会安全认证的企业之一。
威努特以率先独创的“白环境”整体解决方案为核心,研发了覆盖工控网络安全的5大类20款自主可控产品,拥有领先的核心技术及市场优势,成功为电力、轨道交通、烟草、石油石化、市政、智能制造、冶金及军工等国家重点行业五百余家客户提供了全面有效的安全保障,多次受邀为中共十九大、两会、“一带一路”、G20等重大活动进行网络安保工作,广泛参与工控安全领域的国家和行业标准制定,得到了国家多个政府部门和客户的高度认可。
威努特始终以保护我国关键信息基础设施网络空间安全为己任,为“中国制造2025”保驾护航,为建设网络强国添砖加瓦!
渠道合作咨询
刘先生 18500192465 陈女士 15116964490
稿件合作 微信:Luo_xiaoran